// Title of toolset: LSM Transmission Deblurring.txt 
// First version: 05/12/2006

// Description:
// This toolset allows to perform some improvements on images obtained with Laser Scanning Microscopy (LSM)
// in transmission mode:
// Deblurring with usable default parameters values or user customized settings.
// Removing of horizontal interference streaks with usable default parameters values or user customized settings.
// Complete cleaning image treatment: deblurring and removing of horizontal streaks.
// more informations, and demo images are available from the internet resources of the toolset.
// A part of this tool is based on the two following ImageJ macros:
// from http://rsb.info.nih.gov/ij/macros/FFTRemoveStreaks.txt
// from http://rsb.info.nih.gov/ij/macros/GaussianConvolution.txt

// Author : Gilles Carpentier
// Faculte des Sciences et Technologies,
// Universite Paris 12 Val de Marne, France.

var  matrixchoice =newArray ("3","5","7","15","23","33","63"),defaultmatrix="33";
var  passes=newArray ("2","3","4","5","6","7","8","9"),defaultpass="4";
var optimize=1,sigmamini=1,sigmamax=40;

var percent = 0.005, sdhight = 3.5, largeHF= 0.002,optimizefft=1;

var onlinedoclink = "http://image.bio.methods.free.fr/lsmtrans.html";
var urllist = "http://image.bio.methods.free.fr/ij/ijupdatetest/ListOfMacros.txt";// to check the internet access
var demoimagelink1 = "http://image.bio.methods.free.fr/ij/ijmacro/lsm/Myoblast-init.tif.zip",demoimagename1="Myoblast-init.tif";
var demoimagelink2 = "http://image.bio.methods.free.fr/ij/ijmacro/lsm/Nerve.tif.zip",demoimagename2="Nerve.tif";

var xx = requires138e(); // check version at install time
function requires138e() {requires("1.38e"); return 0;}

// menu popup summering every commands of the the toolset menu bar
var pmCmds = newMenu("Popup Menu", newArray("Abort Process","-","Deblurring With Default Settings or Last User Settings","Deblurring With Custom Settings","-", "Removing Streaks With Default Settings or Last User Settings","Removing Streaks With Custom Settings","-","Deblurring and Removing Horizontal Streaks","-","Download\/Open LSM Myoblast-init Image","Download\/Open Phase Contrast Nerve Image","-","About LSM Transmission Deblurring","-","On Line Documentation"));

macro "Popup Menu" {
	cmd = getArgument();
	if (cmd !="-" && cmd =="Abort process")  {abortProcess ();}
	if (cmd !="-" && cmd =="Deblurring With Default Settings or Last User Settings")  {Debluring (0);}
	if (cmd !="-" && cmd =="Deblurring With Custom Settings")  {Debluring (1);}
	if (cmd!="-" && cmd == "Removing Streaks With Default Settings or Last User Settings") {removeStreaks (0);}
	if (cmd!="-" && cmd == "Removing Streaks With Custom Settings") {removeStreaks (1);}
	if (cmd!="-" && cmd == "Download\/Open LSM Myoblast-init Image") {OpenImageLink(0,demoimagelink1,demoimagename1);}
	if (cmd!="-" && cmd == "Download\/Open Phase Contrast Nerve Image") {OpenImageLink(0,demoimagelink2,demoimagename2);}
	if (cmd!="-" && cmd == "Deblurring and Removing Horizontal Streaks") {cleanLSMTransmission ();}
	if (cmd!="-" && cmd == "About LSM Transmission Deblurring") {about1();}
	if (cmd!="-" && cmd == "On Line Documentation") {doc ();}
}

macro "Unused Tool-1 - " {}  // leave slot between text tool and magnifying glass unused

// macro LSM Transmission and Phase Contrast Deblurring Menu Tool 
var uCmds = newMenu("LSM Transmission and Phase Contrast Deblurring Menu Tool",newArray("Deblurring With Default Settings or Last User Settings","Deblurring With Custom Settings","-","Removing Streaks With Default Settings or Last User Settings","Removing Streaks With Custom Settings","-","Deblurring and Removing Horizontal Streaks","-","Download\/Open LSM Myoblast-init Image","Download\/Open Phase Contrast Nerve Image"));
macro "LSM Transmission and Phase Contrast Deblurring Menu Tool - C000C001C002C003C004C005C006C007C107C108C208C209C20aC30aC30bC40bC40cC50cC50dC60dD5aD6aD7aD8aC60dC70eD59D69D79D89C70eD58D68D75D78D85D88C70eD48D49D4aD65C70eD7cD8cC70eD55C80dD6cD84C80dD74C80dD64C80dC90dC90cD5cC90cC90bD38D83C90bD39D45Ca0bD54Ca0bD73Ca0aD3aCa0aD56D57D66D67D76D77D86D87Ca0aD6bD7bD8bCa09D47D5bCa09D46Ca08Cb08D4cD63Cb08Cb07D4bD8eCb07Cb06D7eCb06D37Cc06D44Cc06Cc05Cc04D35D93D94D95D96D97D98D99D9aD9bD9cD9dDa3Da4Da5Da6Da7Da8Da9DaaDabDacDadDb4Db5Db6Db7Db8Db9DbaDbbDc4Dc5Dc6Dc7Dc8Dc9DcaDcbDd5Dd6Dd7Dd8Dd9DdaDdbDe7De8De9Cc04D36D53Cc04D9eDb3Cd13D28D6eCd13D29DeaCd13Cd12D8dCd12Cd22D3bD7dCd22Cd21D2aD3cCd21Ce31D6dCe30D82Ce30D5eDe6Ce30D34D43Ce30Ce40D72Ce40DaeCe40D25D27Ce40D81Cf40D00D01D03D04D05D08D09D0aD0cD0eD10D11D13D14D15D18D19D1aD1cD1eD20D21D23D24D2cD2eD30D31D33D3eD40D41D4eD50D51D5dD60D61D70D71D80Cf50D62Cf50D26Cf60D8fCf60D2bCf60D7fCf60D52Cf70D02D06D07D0bD0fD12D16D17D1bD1fD22D2fD32D3fD42D4fD5fD6fCf70Dd4Cf70D4dCf70Cf80D92Cf80DebCf80D0dD1dD2dD3dCf90Dc3Cf90Cfa0Da2Cfa0Cfb0De5Cfb0Cfc0Cfd0Df8Cfd0Df9Cfd0Cfe0Df7Cfe0Cff1Db2Cff2Cff3Cff4Cff5DfaCff6Dd3Cff7D90D91D9fDa0Da1DafDb0Db1Dc0Dc1Dc2Dd0Dd1Dd2De0De1De2De3De4Df0Df1Df2Df3Df4Df5Df6DfbCff8Cff9CffaCffbCffcCffdCffeCfffDbcDbdDbeDbfDccDcdDceDcfDdcDddDdeDdfDecDedDeeDefDfcDfdDfeDff"{
	cmd = getArgument();
	if (cmd!="-" && cmd == "Deblurring With Default Settings or Last User Settings") {Debluring (0);}
	if (cmd!="-" && cmd == "Deblurring With Custom Settings") {Debluring (1);}
	if (cmd!="-" && cmd == "Removing Streaks With Default Settings or Last User Settings") {removeStreaks (0);}
	if (cmd!="-" && cmd == "Removing Streaks With Custom Settings") {removeStreaks (1);}
	if (cmd!="-" && cmd == "Deblurring and Removing Horizontal Streaks") {cleanLSMTransmission ();}
	if (cmd!="-" && cmd == "Download\/Open LSM Myoblast-init Image") {OpenImageLink(0,demoimagelink1,demoimagename1);}
	if (cmd!="-" && cmd == "Download\/Open Phase Contrast Nerve Image") {OpenImageLink(0,demoimagelink2,demoimagename2);}
}

macro "Abort Process Action Tool - C810Dc2Df7Ca55D42D51Ce20D7dD8cDd6CfffD88Da7Cd20DadCfedD3eD55D5bDa9Dc1Ce40D63De6CfffD00D01D03D04D05D06D07D08D09D0aD0cD0dD0eD0fD10D11D14D1cD1dD1eD1fD20D21D22D2fD31D3fD40D66D6aDaaDb0Db5DbbDc0De0DefDf0Df1Df2Df3DfdDfeDffC811Da1Dd3Cc77D1bD6cCe20Dc7CfffD23D65D79DdfCc31D68Da4CeffDeeCd52D27D4dC910D7fD8fDbfDf9Cd64D4bD75Db7Dc6Ce30D39D47D48D74D85Da3CfffD13D30Da6Dd0De1Cc20DacDbdDdaDdbCfffD98Cd42D28D52D5eDe5Ca21D71D81D91DcaCfecD5aD67D69D96Cf30D3aD3bD94Db3Cc32D25D2bD34D9bCfffD12D50D70D80D87D89D90D99Da0Db6Dd1De2Cf63D64D72D82Db2DbeC910D9fDafDecDf8Cb66D17D19D1aDa8Ce20D37D49Dd7Dd8CeffD6bD77D97Cd20D6dD7cDc9CffeD4fD60D7aD9aDbaCf52D35D44D53D6eC821D5fD61De4DfbCebbD15DbcDcbDcfDdeCf30D58D73D83D93Cd41D3cD95De7CfffD2eD78Cf53Dc3DcdDd4DebCa20D6fDccCc75D18D24D5cD7bD8aCf30D36D84Cd30D46D59D8bDd5CfffD02D0bD2dD41D76Cf42D26D8eD9eDdcCa32D2cD3dD4eDb9CfedD56Da5Dd2DedDfcCe31D2aD57D5dDeaCc41D43D4cD86DaeCf63D62D92Da2C810DddDf6DfaCa66D16D33Ce30Dc8Cd20D8dD9cD9dDd9CfeeD32DabDe3Df4Cd51D29D7eC822Db1Df5Cea7Db4Dc5Ce30D4aDb8De9Cd40D38Dc4De8Cd53D45D54C911Dce" {
	abortProcess ();
}

macro "On Line Documentation Action Tool - C000Da9DadDb6DbdDc5Dc6Dd3Dd4Dd5Dd6DddC20fD11D12D13D14D15D16D17D18D19D1aD1bD1cD1dD1eD1fC0f3D42D43D44D45D46D47D48D49D4aD4bD4cD4dD4eD4fC0feD32D33D34D35D36D37D38D39D3aD3bD3cD3dD3eC444DdeDefC73fD01Cfd0D62D63D64D65D66D67D68D69D6aD6bD6cD6dD6eCeeeD90D95Da1Da4Db0Db2Db3De0De8Df0Df7DfaC222DeeC06fD22D23D24D25D26D27D28D29D2aD2bD2cD2dD2eC7f0D52D53D54D55D56D57D58D59D5aD5bD5cD5dD5eCcccDbfDf9Cf74D70Ca99D97C888Da8CfffD9bD9cC000Dc4Dd2C64fD10C0f4D41C0ffD31D3fCf40D71D72D73D74D75D76D77D78D79D7aD7bD7cD7dD7eD7fCa7fD00Cfd0D61D6fCfefD91C444Db5DdaDe9C06fD21D2fC7f0D51D5fCeddD96Cf88D82D83D84D85D8bD8cCaaaDccDeaDfdC999DcfCfffD9fDafDb1Db8De1C666Dc7C84fD02D03D04D05D06D07D08D09D0aD0bD0cD0dD0eC333Da6Da7DaaDb9DbcDd9DdcCdddD9aDa2Da3Dc8DdbDecCaaaDabDaeDc1De3De4De5De6Cf89D8dC222DcdDedDfeDffC4ffD30CfffDebDf1Df2Df3Df4Df5Df6DfcC48fD20C4f6D40CeeeD92D93D94Da0DcbDf8DfbCbbbDb4Dd8C9f4D50C555Dc2C73fD0fC333DbbDc3Dc9Dd1CdddDe7Cf89D81D86D8aD8fC111DbaDd7CdeeDa5CbbbDb7Dc0De2Cf99D87D88D89C777DacDcaCcbbD9eCfaaD80C999D98Cf89D8eC999D9dC766D99C555DceC888DbeCfd4D60C777DdfC666Dd0"{
	doc ();
} 

macro "Version and Update Infos Action Tool - CcccD5fD6fD7fD8fD9fC78bD17D19D2aD33D37D3bD42D4cD75D95DceDd5Dd9De6Df7Df9CddeDa3C36bD27D28D3aD57D58D59D66D76D77D86D87Da7Db8Dd6De8De9CeeeD00D01D02D04D06D07D08D09D0bD0dD0fD10D11D12D14D1bD1dD1fD20D21D22D2dD30D31D32D40D46D47D48D49D50D5bD60D70D71D72D74D7dD80D81D82D84D8dD90D91D92D94D9dDa0Da1Da2Da4Db0Db1DbbDc0Dc1Dc6Dc7Dc8Dc9Dd0Dd1Dd2De0De1De2DedDf0Df1Df2Df4DfbDfdDffC8beD3cD3dD4dD5aD6aD79D7aD7bD85D8bD9aDaaDc3Dc4Dd3Dd4CeeeD03D05D0aD0cD0eD13D15D1cD1eD23D2eD3eD4aD55D6cD73D7cD7eD83D8cD8eD93D9cD9eDb5DcaDdeDe3DeeDf3Df5DfcDfeC559D18D26D34D35D36D41D51D61DafDbfDcfDdaDdbDddDeaDf8CcddD2fD5cD6dD6eDabDb2Db4Dc2DefC99bD16D24D39D45D54D56D64D65Da5DacDb6DbcDcbDd7DecDfaCdefD67D8aC59dD29D2bD68D69D78D88D96D97D98D99Da6Da8Da9Db9De5De7CacdD1aD2cD38D4bD4eD5dD5eD6bD89D9bDb3DbaDc5Dd8De4Df6C348D25D43D44Db7DccDdcDebCcccD3fD4fDdf" {
	VersionInfos ();
}

macro "About LSM Transmission Deblurring Action Tool - C000D84Cb9fD25De7CaaaD14D2dDa0DafDecDfaCedfD49D4aD4bD4cD58D68D9bDb9DbaDbbDbcC889D2cDebCddfD52CcccD0bD22CeeeD00D03D0cD0fD10D1fD20D2fD30D40Dc0Dd0DdfDe0DefDf0Df1Df2Df3DfcDfeDffC666D07D70CdcfD34D35Dc4CbacD86D91CfefD6bD6dD7cD8cD8dD8eD9cD9dDadC97aDd3De5CedfD99CeeeD01D02D04D0dD0eD11D12D1eD21D3fDcfDd1De1De2DeeDf4DfdCfefD7dC545D94Da5CdbeDa4Da7CbabD05D50DaeCfefD7eC98aD32Da1CecfD39D3aD3bD46D48D57D67Da8Db6Db8Dc9DcaDcbDccCdcdD81C878D1bD60D65CdcfD29D36D38D47D77Db7Dc8Dd9DdaCcbcD7aDbfDc1De3C98bD16D24D75DeaCedfD56D66D73D76D83D93Da3C212D7bD88D96D97CcaeD26D3cDdbCaaaD3eD5fCfdfD59C889D15D1aD78Dc2CdcfD45Db4Db5Dc6CdddD13D31D4fDdeDedDfbC777D09D7fD85D90Df7CeceDbdCbadD18D55Db2De9Ca9aD5eDcdDceDdcC656D08D64D80D87D8bCdbfD28D2aD37Dc7Dd8CbbbD1cD42Dd2Df5CfdfD5aD5bD5cD5dD69D6aD6cD9aDa9DabDacC999D0aD41DddDf6CdddD1dD2eD9eDb0C888D06D4eD6fD9fDf9CcbdD54D71D98Dc3Ca9dD17D19Dd4De6C000D74D79D95CcafDd5Dd6De8CedfD62D72D92C889D51Db1DbeCedfD53D63Da2CdcdD6eC777D8fDf8CdcfD43D44Db3Dc5CbadD2bD33C99aD23De4C545D89Da6CcbfD27Dd7CbabD61CedfD82DaaC98aD3dCdceD4dD8a" {
	about1();
}

// functions like macros

function Debluring (custom) {
	setBatchMode(true);
	starttime = getTime();
	imaname = getTitle;depth = bitDepth;
	if (depth > 8) {showMessageWithCancel ("This macro works with 8 bit images. Do you want to\nconvert it and continue the process?");}
	if (depth > 8) run("8-bit");
	imagey = getHeight();imagex = getWidth();
	if (custom == 1) getdeblurParam();

	defaultmatrix=parseFloat (defaultmatrix);
	defaultpass= parseFloat (defaultpass);
	sigmamini=parseFloat (sigmamini);
	sigmamax=parseFloat (sigmamax);

	workingStack= makeStack (imaname,imagex,imagey,defaultpass);
	setPasteMode("Copy");
	selectImage(imaname);run("Select All");run("Copy");selectWindow(workingStack);setSlice(1);run("Paste");run("Select None");
	range=(sigmamax-sigmamini); steps= (range/(defaultpass-1));
	for (i=1; i<=defaultpass; i++) {
		nette (workingStack,i,defaultmatrix,(sigmamini+(i-1)*steps));
	}
	sumnette (workingStack);
	selectWindow(workingStack); setSlice(2);
	final=duplicate (workingStack,"1");
	if (lastIndexOf(imaname, ".") > 0) {imaname = substring (imaname,0,lastIndexOf(imaname, "."));}
	rename(imaname + "-Deblured" );
	if (optimize ==1) {run("Enhance Contrast", "saturated=0.5 normalize");}
	selectWindow(workingStack);close();
	setBatchMode("exit and display");
	seconds = (getTime-starttime)/1000;
	//print("Time to perform the process= "+ seconds);
}

function removeStreaks (custom) {

	// Based on http://rsb.info.nih.gov/ij/macros/FFTRemoveStreaks.txt
	nomdimage = getTitle;depth = bitDepth;
	imageid = getImageID();
	if (depth > 8) {showMessageWithCancel ("This macro works with 8 bit images. Do you want to\nconvert it and continue the process?");}
	if (depth > 8) run("8-bit");
	imagey = getHeight();
	imagex = getWidth();
	if (custom == 1) {getfftParam();}
	setBatchMode(true);
	wokimimage=duplicate (nomdimage,1);
	if (isOpen("Transmission_Filter")) {
		selectWindow("Transmission_Filter");
		run("Close");
	}
	size =imagex;
	newImage("Transmission_Filter", "8-bit black", size, size, 1);
	width=3;halfwidth=(floor(width/2));
	barre(((size/2)-halfwidth),0,width,size);
	matrice= matrix(9,40); // to adjust
	selectWindow("Transmission_Filter");
	it=4; // to adjust
	for (nconv=0;nconv <it;nconv++) {
		run("Convolve...", "text1=["+ matrice+"] normalize");
	}
	longueur=floor(size*percent);
	width=largeHF*imagex; 
	if (width<1) {width =1;}
	halfwidth=(floor(width/2)); 
	barre(((size/2)-halfwidth),0,width,longueur);
	barre(((size/2)-halfwidth),(size-longueur),width,longueur);
	matrice= matrix(13,sdhight);// to adjust
	run("Convolve...", "text1=["+ matrice+"] normalize");
	run("Enhance Contrast", "saturated=0 normalize");
	run("Invert");
	selectImage(wokimimage);
	run("32-bit");
	run("Custom Filter...", "filter=Transmission_Filter");
	run("8-bit");
	if (optimize ==1) {run("Enhance Contrast", "saturated=0.5 normalize");}
	if (lastIndexOf(nomdimage, ".") > 0) {nomdimage = substring (nomdimage,0,lastIndexOf(nomdimage, "."));}
	rename(nomdimage + "-fft" );
	run("Select None");
	selectWindow("Transmission_Filter");close();
	setBatchMode("exit and display");
}

function openmyoblast () {OpenImageLink(0,demoimagelink1,demoimagename1);}

function opennerve () {OpenImageLink(0,demoimagelink2,demoimagename2);}

function abortProcess () {setKeyDown("Esc");}

function cleanLSMTransmission () {
	Debluring (0);
	removeStreaks (0);
}

function doc () {
	if (File.openUrlAsString(urllist) == "") exit("You need an internet access to run this function.");
	showMessageWithCancel  ("A notice is avaible on line. Open it with your default web browser?");
	run("URL...", "url=["+onlinedoclink +"]");
}

// Functions specific to fft remove streaks

function getfftParam() {
	Dialog.create("User Parameters for FFT Removing Streaks");
	Dialog.addMessage("Choose the frequency masks parameters:");
	Dialog.addNumber("Percent of the half vertical axis of power spectra for hight frequencies:", percent, 3, 4, "");
	Dialog.addNumber("Percent of the horizontal axis of power spectra for hight frequencies:", largeHF, 3, 4, "");
	Dialog.addNumber("Standard Deviation of gaussian transition for hight frequencies:", sdhight, 1, 3, "");
	Dialog.addCheckbox("Normalized histograms 0.5 % saturation", optimizefft);
	Dialog.show();
	percent = Dialog.getNumber();
	largeHF = Dialog.getNumber();
	sdhight = Dialog.getNumber();
	optimizefft=Dialog.getCheckbox();
}

function barre(barx,bary,largbar,hautbar) {
    makeRectangle(barx, bary, largbar, hautbar);
    setForegroundColor(255, 255, 255);
    run("Fill");
    run("Select None");
}

// Common functions, and functions specific to the deblurring

function getdeblurParam() {
	Dialog.create("User Parameters for Deblurring");
	Dialog.addMessage("Choose the size of the matrix, the number \nof passes (range size of details), and the \noptionnal enhance contrast.");
	Dialog.addChoice("Size of the matrix", matrixchoice, toString(defaultmatrix));
	Dialog.addChoice("Number of passes", passes, toString(defaultpass));
	Dialog.addNumber("Minimal Standard Deviation", sigmamini, 1, 3, "");
	Dialog.addNumber("Maximal Standard Deviation", sigmamax, 1, 3, "");
	Dialog.addCheckbox("Normalized histograms 0.5 % saturation", optimize);
	Dialog.show();
	defaultmatrix=Dialog.getChoice();
	defaultpass= Dialog.getChoice();
	sigmamini=Dialog.getNumber();
	sigmamax=Dialog.getNumber();
	optimize=Dialog.getCheckbox();
}

// square function
function carre (car) {
	car= (car * car);
	return car;
}

// gaussian convolution matrix function
// from http://rsb.info.nih.gov/ij/macros/GaussianConvolution.txt
function matrix (taille,gauss) {
	matrice="";
	for (j=0; j < taille; j++) {
		lignea="";
		for (i=0; i < taille; i++) {
			numer = -(carre(i-floor(taille/2)) + carre(j-floor(taille/2)));
			denom = 2 * carre(gauss);
			coeff=exp(numer/denom);
			lignea = lignea + " " + coeff;
		} 
	matrice = matrice + lignea + "\n";	
	}
	return matrice;
}

function duplicate (imaname,num) {
	selectWindow(imaname);
	run("Select None");
  	run("Duplicate...", "title=blured_"+num);
	nomwork = getTitle;
	return nomwork;
}

function makeStack (imaname,x,y,num) {
	newImage(imaname + "-work", "8-bit", x,y, (num+2));
	nomwork = getTitle;
	return nomwork;
}

function nette (stack,nbpass,matrixsize,sigma) {
	selectWindow(stack);setSlice(1);
	blured=duplicate (stack,1); matrice=matrix (matrixsize,sigma);
	run("Convolve...", "text1=["+ matrice+"] normalize");
	selectWindow(stack);setSlice(1);
	init=duplicate (stack,2); 	
	imageCalculator("subtract create 32-bit ", init, blured);
	resultimage = getTitle;rename("resultat");
	run("8-bit");
	run("Select All");run("Copy");selectWindow(stack);setSlice(2+nbpass);run("Paste");run("Select None");
	selectImage ("resultat"); close();selectWindow(blured);close();selectWindow(init);close();
}

function addnett (stack,slc1,slc2,scldest) {
	selectWindow(stack);setSlice(slc1);
	nette1=duplicate (stack,1);
	selectWindow(stack);setSlice(slc2);
	nette2=duplicate (stack,2);
	imageCalculator("Add create 32-bit ", nette1, nette2);
	resultimage = getTitle;rename("resultat"); run("8-bit");
	run("Select All");run("Copy");selectWindow(stack);setSlice(scldest);run("Paste");run("Select None");
	selectWindow(nette1);close();selectWindow(nette2);close();selectImage ("resultat"); close();
}

function sumnette (stack) {	
	selectWindow(stack);nbit=(nSlices-2);
	for (i=1; i<=nbit; i++) {
		addnett (stack,2,(i+2),2);
	}
}

function about1() {
	about="";
	about=about + "\n                                        -- LSM Transmission Deblurring --";
	about=about + "\n \n* Description:";
	about=about + "\n \nThis toolset allows to perform some improvements on images obtained with Laser Scanning";
	about=about + "\n Microscopy (LSM) in transmission mode. It can also be used in phase contrast microscopy.";
	about=about + "\n \n* Notice:";
	about=about + "\n \n   - The \"LSM Transmission and Phase Contrast Deblurring Menu\" regroups the different "; 
 	about=about + "\n   functions. These are also available by right click onto an image (control click for Macintosh";
	about=about + "\n   withsingle button user interface device):";
	about=about + "\n \n      - \"Deblurring With Default Settings or Last User Settings\" sub-menu allows to enhance";
	about=about + "\n      details in phase contrast or transmission LSM images. It also removes eventual";
	about=about + "\n      shadings. The default settings gives good results in most of cases. They can be";
	about=about + "\n      customized using the \"Deblurring With Custom Settings\" sub-menu.";
	about=about + "\n  \n     - \"Removing Streaks With Default Settings or Last User Settings\" sub-menu allows to";
	about=about + "\n      remove horizontal interference streaks, often present in transmission LSM images,";
	about=about + "\n      particularly visible after deblurring. The default settings gives good results in most of cases.";
	about=about + "\n      Optimize the removal of hight frequencies streaks using the \"Removing Streaks With";
	about=about + "\n      Custom Settings\" sub-menu.";
	about=about + "\n  \n     - \"Deblurring and Removing Horizontal Streaks\" sub-menu performs a complete cleaning";
	about=about + "\n       of transmission LSM images. If the deblurring and\/or remove streaks functions were optimized";
	about=about + "\n       by the user, these parameters will be used.";
	about=about + "\n  \n     - Demo lsm and phase contrast images for testing settings are downloadable from the two sub-"; 
	about=about + "\n       menus \"Download\/Open LSM Myoblast-init Image\" and \"Download\/Open Phase Contrast";
 	about=about + "\n       Nerve Image\".";
	about=about + "\n \n  - Click on the \"Abort Process\" ImageJ tool bar icon to cancel too long processes.";
	about=about + "\n  - Click on the \"On Line Documentation\" ImageJ tool bar icon for more details.";
	about=about + "\n  - Click on the \"Version and Update Infos\" ImageJ tool bar icon to look for new beta versions.";

	about=about + "\n-------------------------------------------------------------------------------------------------------------";
	about=about +"\nAuthor: Gilles Carpentier"+"\nFaculte des Sciences et Technologies"+"\nUniversite Paris 12 Val de Marne, France.";
	showMessage(about);
	//print(about);
}

function OpenImageLink(question,demoimagelink,demoim) {
	// Check if already downloaded.
	if (isOpen(demoim)) exit ("The \"" + demoim + "\" is already open.");
	demoimalocation = getDirectory("startup");	
	fildestination = demoimalocation+ "Downloaded Demo Images/" + demoim;
	if (File.exists(fildestination) && ! isOpen(demoim)) {
		if (question ==1 ) showMessageWithCancel ("The \"" + demoim + "\" has already been downloaded. Open it?");
		open(fildestination);
	}
	else {
		if (! File.exists(fildestination)) {
			if (File.openUrlAsString(urllist) == "") exit("You need an internet access to run this function.");
			showMessageWithCancel ("ImageJ will download a demo image. Continue?");
			run("URL...", "url=["+demoimagelink+"]");
			imageid = getImageID();
			nomdimage = getTitle;
			// Create a <Downloaded Demo Images> repertory in ImageJ folder.
			ImaDemo = demoimalocation+"Downloaded Demo Images"+File.separator;
			File.makeDirectory(ImaDemo);
			if (!File.exists(ImaDemo)) exit("Unable to create directory, something wrong in the ImageJ folder");
			selectWindow(nomdimage);
			save(""+ImaDemo+""+ nomdimage +"");
		}     
	}
}

// --- End of code of the macro project ---//
// ----------------------------------//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
// -------------------*** Additionnal code for on line update resources ***-----------------------------

//Developer info
//Kind:Toolset
//Title:"LSM Transmission Deblurring" 
//Version:1.0
//Date: 10 December 2006
//Origin:NIH
//End info

function VersionInfos () {
	// variables for on line update resources
	beginsign="//Developer info";endsign="//End info"; 
	kind="toolsets/"; 
	urlrep="http://image.bio.methods.free.fr/ij/ijmacro/lsm/";
	name="LSM Transmission Deblurring.txt"; 
	namedev="LSM Transmission Deblurring-dev.txt"; 
	favoritefoldername= "Image.Bio.Methods";

	version=versionMessage();
	if (indexOf(version, "install it?" ) > 0 ) {
		macrotext=getdistantmacro (namedev,urlrep);macrolocal="";
		macropath=getDirectory("macros")+kind+namedev;
		if (File.exists(macropath)) {macrolocal=File.openAsString(macropath);}
		if (macrotext != macrolocal) {
			//perfom the installation
			Dialog.create("New version installation option");
			Dialog.addMessage(version);
			Dialog.addCheckbox("Install a Plugin Shortcut?", 0);
			Dialog.addMessage("(This option provides a shortcut in the plugins menu of ImageJ, making easier\nthe next use of the new installed version).");
			Dialog.show();
			plugin= Dialog.getCheckbox();
			f= File.open(macropath);
			print (f,macrotext);
			File.close(f);
			if (plugin ==1) {InstallPluginsStarter(namedev);}
			message="The installation of the "+giveDevInfo (macrotext,1)+ " "+ giveDevInfo (macrotext,2)+ "is completed.";
			message=message+ " Do you want to run it?";
			showMessageWithCancel(message);
			run("Install...", "install=["+macropath+"]");
		}
	} else {showMessage (version); // comment without installation available}
}

function versionMessage() {
	
	version="";
	if (getDirectory("startup") == 0) exit ("Unable to find the startup directory, something wrong in the ImageJ folder");
	if (getDirectory("macros") == 0) exit ("Unable to find the macros directory, something wrong in the ImageJ folder");
	MacroPath=getDirectory("macros");thismacropath=MacroPath+kind+name;
	if (! File.exists(thismacropath)) exit ("This macro has to be recorded under the name of \"" +name+"\"\ninto the \"macros/"+kind+"\" folder of ImageJ.");

	macrotext=File.openAsString(thismacropath);
	macrotextdistant=getdistantmacro (namedev,urlrep);

	version="";macrolocal="";
	version=version + "\n \nThis version of the " + giveDevInfo (macrotext,1) + " " + giveDevInfo (macrotext,2);
	version=version + "is provided by the " + giveDevInfo (macrotext,5)+ " web site.";
	version=version + "\nVersion number: " + giveDevInfo (macrotext,3)+ " - " + giveDevInfo (macrotext,4) +".";
	
	if (macrotextdistant !="" ) {
		new=giveDevInfo (macrotextdistant,3);old=giveDevInfo (macrotext,3);
		if (new > old) {
			macropath=getDirectory("macros")+kind+namedev;
			if (File.exists(macropath)) {macrolocal=File.openAsString(macropath);}
			if (macrotextdistant != macrolocal) {
				update="\n \nA new beta version "+new+ " is available on the "  +giveDevInfo (macrotextdistant,5)+ " web site: ";
				update=update+ "\n \nDo you want to install it?";
			} else {
				update ="\n \nThe new "+new+" beta version called \"" +namedev+ "\" provided by \nthe "+giveDevInfo (macrotextdistant,5) +" web site has already be installed";
				update = update+ " in the \"" +kind+ "\" repertory \nof ImageJ.";
			}
		} else {
			update="No new Beta version available.";
		}
		version=version +"\n" + update ;
	} 
	return version; 
}

function giveDevInfo (text,n) {
	lines=split(text,"\n");
	if ( (indexOf(text, beginsign)<0) || (indexOf(text, endsign)<0) ) exit ("Not upgradable macro code.");
	for (i=0; lines[i] != endsign; i ++) {}
	for (j=i; lines[j] != beginsign; j --) {}
	infotext=newArray(i-j-1);
	for (i=0; i < infotext.length; i ++) {infotext[i]=lines[i+j+1];}
	info=infotext[n-1]; signature=":";
	cut = indexOf(info, signature);
	info = substring(info,(cut+lengthOf(signature)),lengthOf(info));
	return info;
}

// Function giving the content of a distant macro (name) located at the distant repertory (urlrep).
function getdistantmacro (name,urlrep) {
	macrotextnih="";
	if (File.openUrlAsString("http://rsb.info.nih.gov/ij/macros/Arrays.txt") != "") {
		distantmacrolink = urlrep + name;
		if (indexOf(distantmacrolink, " ") > -1) {
			while (indexOf(distantmacrolink, " ") > -1) {
				distantmacrolink=substring(distantmacrolink, 0, (indexOf(distantmacrolink, " ")))+"%20"+substring(distantmacrolink, (indexOf(distantmacrolink, " ")+1),lengthOf(distantmacrolink) );
			}
		}
		showStatus("Internet link...");
		macrotextnih =File.openUrlAsString(distantmacrolink);
		showStatus("");
	} else { showMessage ("No internet connection to looks for beta version.");}
	return macrotextnih;
}

function InstallPluginsStarter(macroname) {
	// from MacroPluginShortcutsTool.txt
	codestarter = "run\(\"Install...\", \"install=[\"+getDirectory(\"macros\")+\""+kind+ macroname + "\]\"\);";
	if (getDirectory("plugins") == "") exit ("Unable to find the Plugins directory; something wrong in the ImageJ folder.");
	if (endsWith(macroname, ".txt") || endsWith(macroname, ".ijm")) pluginname = substring(macroname, 0, (lengthOf(macroname)-4));
	StarterDir = getDirectory("plugins")+favoritefoldername+File.separator;
	File.makeDirectory(StarterDir);
	if (!File.exists(StarterDir)) exit ("Unable to create "+favoritefoldername+" Macros directory, something wrong in the ImageJ folder.");
	starterplugin = StarterDir + pluginname +"_ .ijm";
	f= File.open(StarterDir + pluginname +"_ .ijm");
	print (f,codestarter);
	File.close(f);
	showMessage ("The plugin shortcut \"" +pluginname+ "\" will be available after\nImageJ restarting, in the \"Plugins->" + favoritefoldername + "\" menu.");
}

// *** End of additionnal code for on line update ressources ***



